package com.hxzy.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.ISelect;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hxzy.common.enums.RCodeEnum;
import com.hxzy.common.exception.MarketException;
import com.hxzy.controller.admin.employee.req.EmployeeAddReq;
import com.hxzy.controller.admin.employee.req.EmployeeEditPwdReq;
import com.hxzy.controller.admin.employee.req.EmployeeEditReq;
import com.hxzy.controller.admin.employee.req.EmployeeSearchReq;
import com.hxzy.controller.admin.employee.resp.EmployeeEditResp;
import com.hxzy.controller.admin.employee.resp.EmployeeResp;
import com.hxzy.controller.admin.login.req.AdminLoginReq;
import com.hxzy.entity.Employee;
import com.hxzy.mapstruct.EmployeeMapStruct;
import com.hxzy.service.EmployeeService;
import com.hxzy.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;

/**
* @author Administrator
* @description 针对表【employee(后台管理员表)】的数据库操作Service实现
* @createDate 2024-04-23 20:22:43
*/
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee>
    implements EmployeeService{

    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public Employee login(AdminLoginReq req) {

        //从redisTempalte读取验证码
        String code = (String) redisTemplate.opsForValue().get("captcha:"+req.getUuid());
        //判断值在不在
        if(code==null){
            throw new MarketException(RCodeEnum.CAPTCHA_EXPIRE);
        }

        //删除验证码
        redisTemplate.delete("captcha:"+req.getUuid());

        //判断验证码是否正确
        if(!code.equals(req.getCode())){
            throw new MarketException(RCodeEnum.CAPTCHA_ERROR);
        }


        //mybatis-plus来写  where条件  login_name='13688888888'
        LambdaQueryWrapper<Employee> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Employee::getLoginName,req.getLoginName());
        //查询
        Employee employee = this.getOne(queryWrapper);

        //判断 用户在不在，  不在抛出异常
        if(Objects.isNull(employee)){
            throw new MarketException(RCodeEnum.ACCOUNT_ERROR);
        }

        //  用户在，判断密码（加密）     判断对不对，如果不对，抛出异常
        if(!BCrypt.checkpw(req.getLoginPwd(),employee.getLoginPwd())){
            throw new MarketException(RCodeEnum.ACCOUNT_ERROR);
        }

         //  用户状态    如果锁定   抛出异常
        if("1".equals(employee.getStatus())){
            throw new MarketException(RCodeEnum.ACCOUNT_LOCKED);
        }
       // 登录成功
        return employee;
    }

    /**
     * 分页查询
     * @param req
     * @return
     */
    @Override
    public PageInfo<EmployeeResp> search(EmployeeSearchReq req) {

        return PageHelper.startPage(req.getPageNumber(),req.getPageSize())
                .doSelectPageInfo(()->{
                    //查询
                    this.baseMapper.search(req);
                });
    }

    @Override
    public boolean add(EmployeeAddReq req) {
        //判断两次密码是否一致
        if(!req.getLoginPwd().equals(req.getLoginPwdConfirm())){
            throw new MarketException(RCodeEnum.ACCOUNT_PASSWORD_ERROR);
        }

        //判断账号是否存在
        if(this.baseMapper.selectCount(new LambdaQueryWrapper<Employee>().eq(Employee::getLoginName,req.getLoginName()))>0){
            throw new MarketException(RCodeEnum.ACCOUNT_EXIST);
        }

        Employee employee=new Employee();
        employee.setLoginName(req.getLoginName());
        employee.setLoginPwd(BCrypt.hashpw(req.getLoginPwd()));
        employee.setGender(req.getGender());
        employee.setStatus(req.getStatus());
        employee.setAvatar(req.getAvatar());
        employee.setRoot("0");

        //当前操作人是谁
        String userName= StpUtil.getExtra("username").toString();
        employee.setCreateBy(userName);
        employee.setCreateTime(new Date());

        return this.save(employee);

    }

    @Override
    public boolean accountExist(String account) {
        if(this.baseMapper.selectCount(new LambdaQueryWrapper<Employee>().eq(Employee::getLoginName,account))>0){
            return true;
        }
        return false;
    }

    @Override
    public EmployeeEditResp findById(Long id) {
        Employee db = this.getById(id);
        if(Objects.isNull(db)){
            throw new MarketException(RCodeEnum.DATABASE_NOT_FOUND);
        }

        //MapStruct来操作
        return EmployeeMapStruct.INSTANCE.convert(db);
    }

    /**
     * 更新数据库的值
     * @param req
     * @return
     */
    @Override
    public boolean edit(EmployeeEditReq req) {
        Employee db = this.getById(req.getId());
        if(Objects.isNull(db)){
            throw new MarketException(RCodeEnum.DATABASE_NOT_FOUND);
        }

        //mapstruct转换
        Employee entity= EmployeeMapStruct.INSTANCE.convert(req);

        //判断密码是否一致 多态
        if(req instanceof EmployeeEditPwdReq){
            EmployeeEditPwdReq  editReq=(EmployeeEditPwdReq)req;
           if(!editReq.getLoginPwd().equals(editReq.getLoginPwdConfirm())){
               throw new MarketException(RCodeEnum.ACCOUNT_PASSWORD_ERROR);
           }

           //密码加密
            entity.setLoginPwd(BCrypt.hashpw(editReq.getLoginPwd()));
        }

        //记录谁做的
        entity.setUpdateTime(new Date());
        entity.setUpdateBy(StpUtil.getExtra("username").toString());
        return this.updateById(entity);
    }
}




